import * as THREE from 'three';
import {Clock, LightShadow} from 'three';
// 导入轨道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';

// 导入快捷界面
// 导入动态纹理加载器
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader';
// 导入动画库
import gsap from 'gsap';

let width = document.getElementsByClassName('pageCan')[0].clientWidth;
let height = document.getElementsByClassName('pageCan')[0].clientHeight;
const group1 = new THREE.Group();
const group2 = new THREE.Group();
const group3 = new THREE.Group();
const group4 = new THREE.Group();
const group5 = new THREE.Group();
const group6  = new THREE.Group();
const group7  = new THREE.Group();
const group8  = new THREE.Group();
const group9  = new THREE.Group();
let arr = [group2,group1,group3,group6,group5,group9,group4,group7,group8]
let scene1 = new THREE.Scene();
let scene2 = new THREE.Scene();
let scene3 = new THREE.Scene();
const camera1 = new THREE.PerspectiveCamera(75, width/ height, 0.1, 180);
const camera2 = new THREE.PerspectiveCamera(75, width/ height, 0.1, 300);
const camera3 = new THREE.PerspectiveCamera(75, width/ height, 0.1, 300);
camera1.position.set(0, 0, 20);
camera2.position.set(0, 0, 20);
camera3.position.set(0, 0, 20);
let renderer1 = new THREE.WebGLRenderer({
  antialias: true, //设置抗锯齿
  alpha: true //背景透明
});
document.body.appendChild(renderer1.domElement);
renderer1.setClearColor(0x000000, 0.0);
renderer1.setSize(width, height);

let renderer2 = new THREE.WebGLRenderer({
  antialias: true, //设置抗锯齿
  alpha: true //背景透明
});
document.body.appendChild(renderer2.domElement);
renderer2.setClearColor(0x000000, 0.0);
renderer2.setSize(width, height);
let renderer3 = new THREE.WebGLRenderer({
  antialias: true, //设置抗锯齿
  alpha: true //背景透明
});
document.body.appendChild(renderer3.domElement);
renderer3.setClearColor(0x000000, 0.0);
renderer3.setSize(width, height);
const axesHelper1 = new THREE.AxesHelper(5);
const axesHelper2 = new THREE.AxesHelper(5);
const axesHelper3 = new THREE.AxesHelper(5);
const controls1 = new OrbitControls(camera1, renderer1.domElement);
controls1.enableDamping = true;
const controls2 = new OrbitControls(camera2, renderer2.domElement);
controls2.enableDamping = true;
const controls3 = new OrbitControls(camera3, renderer3.domElement);
controls3.enableDamping = true;
let clock = new Clock();
scene1.add(camera1);
scene2.add(camera2);
scene3.add(camera3);
// scene1.add(axesHelper1);
// scene2.add(axesHelper2);
// scene3.add(axesHelper3);

const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
const raycaster1 = new THREE.Raycaster();
const pointer1 = new THREE.Vector2();
const mouse = new THREE.Vector2();
let cubeArrr = [];
let cubeArr1 = [];
let smallBall=null;
const params = {
  count: 10000,
  size: 1,
  radius: 5,
  branch: 6,
  rotateRate: 0.3,
  color: '#ff6030',
  endColor: '#6730FF'
};
// 生成顶点
let geom = null;
let material = null;
let points = null;


craeteCan();
createBufferGeometry();
createPointLight();
generateGalaxy();
generPoint();
enviTexture();
hdrTexture();
createBasic();
createMeanless();
animate()
render();

// 点光源
function createPointLight(){
  const AmbientLight = new THREE.AmbientLight('#000', 0.4);
  const PointLight = new THREE.PointLight(0xff00000, 0.1);
  const geometry = new THREE.SphereGeometry(2, 100, 200);
  const material = new THREE.MeshStandardMaterial({ color: 0xffffff });
  const sphere = new THREE.Mesh(geometry, material);
  scene3.add(sphere);
  const planeGeo = new THREE.PlaneGeometry(10, 10);
  const planMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff });
  const plane = new THREE.Mesh(planeGeo, planMaterial);
  plane.position.set(0, -3, 0);
smallBall = new THREE.Mesh(
      new THREE.SphereBufferGeometry(0.3, 20, 20),
      new THREE.MeshBasicMaterial({ color: 0xff00000 })
  );
  smallBall.position.set(Math.random() * 3 + 15, Math.random() * 3 + 15, Math.random() * 3 + 15);
  smallBall.add(PointLight);
  plane.rotation.x = -Math.PI / 2;
  renderer3.shadowMap.enabled = true;
  PointLight.castShadow = true;
  sphere.castShadow = true;
  plane.receiveShadow = true;
  PointLight.shadow.radius = 20;
  PointLight.shadow.mapSize.set(512, 512);
  PointLight.decay = 0;
  group3.add(plane)
  group3.add(smallBall)
  scene3.add(AmbientLight);
  scene3.add(group3);
  scene3.add(group3);
  group3.position.set(0, 0, 0);

}
// 三角形
function createBufferGeometry(){
  var mesh = null;
  for (let i = 0; i < 100; i++) {
    // 三角形需要三个顶点一个顶点三个值 3*3 = 9
    const geo = new THREE.BufferGeometry();
    const postionArr = new Float32Array(9);
    for (let j = 0; j < 9; j++) {
      postionArr[j] = Math.random() * 10 - 5;
    }
    let color = new THREE.Color(Math.random(), Math.random(), Math.random())
    geo.setAttribute('position', new THREE.BufferAttribute(postionArr, 3));
    const cubeMaterail = new THREE.MeshBasicMaterial({ color: color, transparent: true, opacity: 0.6 });
    mesh = new THREE.Mesh(geo, cubeMaterail);
    group1.add(mesh)
    scene2.add(group1)
    group1.position.set(0, 0, 0);
  }
}
// 镭射交互
function craeteCan(){
  const textureLoader = new THREE.TextureLoader();
  const texture = textureLoader.load('./textures/matcaps/vdekdjrc_4K_Roughness.jpg');
  const bumpMap  = textureLoader.load('./textures/matcaps/vdekdjrc_4K_Roughness.jpg');
  const light = new THREE.HemisphereLight(0xffffff, 0x888888);
  light.position.set(0, 1, 0);
  scene1.add(light);
  window.addEventListener('click', onMouseMove);
  const cubeGeo = new THREE.IcosahedronGeometry(0.5, 3);
  const material = new THREE.MeshPhongMaterial({
    color: '#fff',
    map: texture,
    bumpMap:bumpMap,
  });
  const light1 = new THREE.PointLight(0xff0000, 1, 100);
  light1.position.set(50, 50, 50);
  const geo = new THREE.SphereGeometry(1, 50, 50);
  const m1 = new THREE.MeshBasicMaterial({
    color: '#fff'
  });
  const sp = new THREE.Mesh(geo, m1);
  sp.add(light1);
  // group2.add(sp)
  // scene1.add(group2);
  for (let i = -4; i < 4; i++) {
    for (let j = -4; j < 4; j++) {
      for (let z = -4; z < 4; z++) {
        const cube = new THREE.Mesh(cubeGeo, material);
        cube.position.set(i, j , z );
        group2.add(cube)
        scene1.add(group2);
        cubeArrr.push(cube);
      }
    }
  }
  group2.position.set(0, 0, 0);
}
// 银河系
function generateGalaxy() {
  const textureLoader = new THREE.TextureLoader();
  const texture = textureLoader.load('./textures/particles/1.png');
  const startColor = new THREE.Color(params.color);
  const endColor = new THREE.Color(params.endColor);
  geom = new THREE.BufferGeometry();
  const positions = new Float32Array(params.count * 3);
  const colors = new Float32Array(params.count * 3);

  for (let i = 0; i < params.count; i++) {
    const current = i * 3;
    // 当前点再哪一条分支角度上
    const branchAngle = (i % params.branch) * ((2 * Math.PI) / params.branch);
    // 当前点距离圆心的距离
    let distance = Math.random() * params.radius * Math.pow(Math.random(), 3);
    const randomX = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 15;
    const randomY = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 15;
    const randomZ = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 15;
    positions[current] = Math.cos(branchAngle + distance * params.rotateRate) * distance + randomX;
    positions[current + 1] = 0 + randomY;
    positions[current + 2] = Math.sin(branchAngle + distance * params.rotateRate) * distance + randomZ ;
    // 混合颜色生成渐变色
    const mixColor = startColor.clone();
    mixColor.lerp(endColor, distance / params.radius);
    colors[current] = mixColor.r;
    colors[current + 1] = mixColor.g;
    colors[current + 2] = mixColor.b;
  }
  geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));
  geom.setAttribute('color', new THREE.BufferAttribute(colors, 3));
  material = new THREE.PointsMaterial({
    // color: new THREE.Color(params.color),
    size: params.size,
    sizeAttenuation: true,
    depthWrite: false,
    blending: THREE.AdditiveBlending,
    map: texture,
    alphaMap: texture,
    vertexColors: true,
    transparent: true
  });
  points = new THREE.Points(geom, material);
  group4.add(points)
  scene1.add(group4);
  group4.position.set(0, -60, 0);
}
// 雪花
function generPoint(){
  const particGeo = new THREE.BufferGeometry();
  const num = 5000;
  const position = new Float32Array(num * 3);

  const colors = new Float32Array(num * 3);

  for (let i = 0; i < num * 3; i++) {
    position[i] = (Math.random() - 0.5) * 10;
    colors[i] = Math.random();
  }
  particGeo.setAttribute('position', new THREE.BufferAttribute(position, 3));
  particGeo.setAttribute('color', new THREE.BufferAttribute(colors, 3));
  const textureLoader = new THREE.TextureLoader();
  const texture = textureLoader.load('./textures/particles/1.png');
  const PointsMaterial = new THREE.PointsMaterial();
  PointsMaterial.map = texture;
  PointsMaterial.alphaMap = texture;
  PointsMaterial.transparent = true;
  PointsMaterial.depthWrite = false;
  PointsMaterial.blending = THREE.AdditiveBlending;
  PointsMaterial.size = 0.5;
  // PointsMaterial.color.set('yellow');
  PointsMaterial.sizeAttenuation = true;
  PointsMaterial.vertexColors = true;
  const points = new THREE.Points(particGeo, PointsMaterial)
  group5.add(points)
  scene2.add(group5)
  group5.position.set(0,-30,0)
}
// 环境题图
function enviTexture(){
  const geo = new THREE.BoxGeometry(1, 1, 1, 100, 100, 100)
  let event = {};
  event.onLoad = function (options) {
    console.log("图片加载完成", options)
  };
  event.onProgress = function (url, num, total) {
    console.log("图片加载进度", url, num, total, (num / total * 100).toFixed(2))
    let value = (num / total * 100).toFixed(2)
    dom.innerText = value
  };
  event.onError = function (options) {
    console.log("纹理加载错误", options)
  };
  const loading = new THREE.LoadingManager(
      event.onLoad, event.onProgress, event.onError
  );

  const textureLoader = new THREE.TextureLoader(loading)
  const CubeTextureLoader = new THREE.CubeTextureLoader()
      .load( [
        'textures/environmentMaps/0/px.jpg',
        'textures/environmentMaps/0/nx.jpg',
        'textures/environmentMaps/0/py.jpg',
        'textures/environmentMaps/0/ny.jpg',
        'textures/environmentMaps/0/pz.jpg',
        'textures/environmentMaps/0/nz.jpg'
      ]);

  const geometry = new THREE.SphereGeometry( 2, 32, 16 );
  const material = new THREE.MeshStandardMaterial({
    metalness: 1,
    roughness: 0,
    envMap:CubeTextureLoader
  });
  const sphere = new THREE.Mesh(geometry, material);
  group6.add(sphere);
  scene1.add(group6)
  group6.position.set(0,-30,0)
}

// HDR贴图
function hdrTexture(){
  let event = {};
  event.onLoad = function (options) {
    console.log("图片加载完成", options)
  };
  event.onProgress = function (url, num, total) {
    console.log("图片加载进度", url, num, total, (num / total * 100).toFixed(2))
    let value = (num / total * 100).toFixed(2)
    dom.innerText = value
  };
  event.onError = function (options) {
    console.log("纹理加载错误", options)
  };
  const loading = new THREE.LoadingManager(
      event.onLoad, event.onProgress, event.onError
  );
  const textureLoader = new THREE.TextureLoader(loading)
// hdr DataTextureLoader纹理加载器 加载动态hdr
  const rgbeLoader = new RGBELoader()
  rgbeLoader.loadAsync('textures/hdr/002.hdr').then((texture) => {
    texture.mapping =THREE.EquirectangularReflectionMapping,
        group7.background = texture,
        group7.environment = texture
  })
  const CubeTextureLoader = new THREE.CubeTextureLoader()
      .load( [
        'textures/environmentMaps/1/px.jpg',
        'textures/environmentMaps/1/nx.jpg',
        'textures/environmentMaps/1/py.jpg',
        'textures/environmentMaps/1/ny.jpg',
        'textures/environmentMaps/1/pz.jpg',
        'textures/environmentMaps/1/nz.jpg'
      ]);

  const geometry = new THREE.SphereGeometry( 2, 32, 16 );
  const material = new THREE.MeshStandardMaterial({
    metalness: 1,
    roughness: 0,
    envMap:CubeTextureLoader
  });
  const sphere = new THREE.Mesh(geometry, material);


// 设置场景添加背景贴图
// scene.background = CubeTextureLoader
// 设置场景所有物体添加默认的环境
// scene.environment = CubeTextureLoader

// 光源 增加环境光

  const AmbientLight = new THREE.AmbientLight(0XFFFFFF, 0.5); // 柔和的白光

// 增加直线光
// 从上方照射的白色平行光，强度为 0.5。
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  directionalLight.position.set(10, 10, 10)
  group7.add(AmbientLight)
  group7.add(sphere)
  group7.add(directionalLight)
  group7.position.set(0,-60,0)
  scene2.add(group7)
}

// 线框图
function createBasic(){
  window.addEventListener('mousemove', onMove);
  const cubeGeo = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshBasicMaterial({
    wireframe: true
  });

  for (let i = -5; i < 5; i++) {
    for (let j = -5; j < 5; j++) {
      for (let z = -5; z < 5; z++) {
        const cube = new THREE.Mesh(cubeGeo, material);
        cube.position.set(i, j, z);
        group8.add(cube)
        scene3.add(group8)
        group8.position.set(0,-60,0)
        cubeArr1.push(cube);
      }
    }
  }
}

// 金属贴图
function createMeanless(){
  const geo = new THREE.BoxGeometry(8 ,8,8, 1, 100, 100, 100)

  const door = new THREE.TextureLoader().load('./textures/door/color.jpg');

  const doorAplha = new THREE.TextureLoader().load("./textures/door/alpha.jpg")

  const doorao = new THREE.TextureLoader().load("./textures/door/ambientOcclusion.jpg")

  const doorDisplacemen = new THREE.TextureLoader().load("./textures/door/height.jpg")

  const doorRoughnessMap = new THREE.TextureLoader().load("./textures/door/roughness.jpg")

  const doormetalnessMap = new THREE.TextureLoader().load("./textures/door/metalness.jpg")

  const material = new THREE.MeshStandardMaterial({
    map: door,
    alphaMap: doorAplha,
    transparent: true,
    // opacity: 0.8,
    side: THREE.DoubleSide,
    aoMap: doorao,
    aoMapIntensity: 1,
    displacementMap: doorDisplacemen,
    displacementScale: 0.1,
    roughness: 1,
    roughnessMap: doorRoughnessMap,
    metalness: 1,
    metalnessMap: doormetalnessMap
  });
// 增加灯光
// 增加环境光
// const AmbientLight = new THREE.AmbientLight(0XFFFFFF, 0.5); // 柔和的白光
// scene.add(AmbientLight)
// 增加直线光
// 从上方照射的白色平行光，强度为 0.5。
  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  directionalLight.position.set(10, 10, 10)
  group9.add(directionalLight);
  const cube = new THREE.Mesh(geo, material)
  group9.add(cube)

  const planeGeo = new THREE.PlaneGeometry(1, 1, 200, 200)
  const plane = new THREE.Mesh(planeGeo, material)
  plane.position.x = 1
  group9.add(plane)

  planeGeo.setAttribute("uv2", new THREE.BufferAttribute(planeGeo.attributes.uv.array, 2))
  geo.setAttribute("uv2", new THREE.BufferAttribute(geo.attributes.uv.array, 2))
  scene3.add(group9)
  group9.position.set(0,-30,0)
}

function onMove(event) {
  var mainCanvas = document.getElementsByTagName("canvas")[2];
  // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
  pointer1.x = ( (event.clientX - mainCanvas.getBoundingClientRect().left) / mainCanvas.offsetWidth ) * 2 - 1;
  pointer1.y = - ( (event.clientY - mainCanvas.getBoundingClientRect().top) / mainCanvas.offsetHeight ) * 2 + 1;

  raycaster1.setFromCamera(pointer1, camera3);
  // 计算物体和射线的焦点
  const intersects = raycaster1.intersectObjects(cubeArr1);

  let color = new THREE.Color();
  color.r = Math.random();
  color.g = Math.random();
  color.b = Math.random();
  const redMaterial = new THREE.MeshBasicMaterial({
    color: color
  });
  for (let i = 0; i < intersects.length; i++) {
    intersects[i].object.material = redMaterial;
  }
}

/**
 * @description: @zww 监听鼠标移动
 * @param {*} event
 * @return {*}
 */
function onMouseMove(event) {
  var mainCanvas = document.getElementsByTagName("canvas")[0];

  // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
  pointer.x = ( (event.clientX - mainCanvas.getBoundingClientRect().left) / mainCanvas.offsetWidth ) * 2 - 1;
  pointer.y = - ( (event.clientY - mainCanvas.getBoundingClientRect().top) / mainCanvas.offsetHeight ) * 2 + 1;
  raycaster.setFromCamera(pointer, camera1);
  // 计算物体和射线的焦点
  const intersects = raycaster.intersectObjects(cubeArrr);

  let color = new THREE.Color();
  color.r = Math.random();
  color.g = Math.random();
  color.b = Math.random();
  const redMaterial = new THREE.MeshBasicMaterial({
    color: color
  });
  for (let i = 0; i < intersects.length; i++) {
    intersects[0].object.material = redMaterial;
  }
}

/**
 * @description: @zww 更新渲染
 * @param {*}
 * @return {*}
 */
function render() {
  // controls1.update();
  // controls2.update();
  // controls3.update();
  let time = clock.getElapsedTime();
  let deltaTime = clock.getDelta();

  smallBall.position.x = Math.sin(time) *2;
  smallBall.position.z =  Math.cos(time) * 2;
  smallBall.position.y = 3+ Math.sin(time * 10) / 2;
  //根据当前的scrolly设置相机位置
  camera1.position.y = -((window.scrollY/window.innerHeight))*30
  camera2.position.y = -((window.scrollY/window.innerHeight))*30
  camera3.position.y = -((window.scrollY/window.innerHeight))*30
  camera3.position.x = mouse.x * 10
  camera2.position.x = mouse.x * 10
  camera1.position.x = mouse.x * 10

  // camera1.lookAt = new THREE.Vector3 (0,0,1)
  renderer1.render(scene1, camera1);
  renderer2.render(scene2, camera2);
  renderer3.render(scene3, camera3);
  requestAnimationFrame(render);
}

function animate(){
  gsap.fromTo(group1.rotation, { duration: 10, y: Math.PI * 2, repeat: -1, }, { duration: 10, y: 0, repeat: -1, })
  gsap.fromTo(group2.rotation, { duration: 20, y: -Math.PI * 2, repeat: -1, }, { duration: 20, y: 0, repeat: -1, })
  gsap.to(group3.position,{ y: 0,
    duration: 0.5,
    ease: "power2.inOut",
    repeat: -1,
    yoyo: true,})
  gsap.fromTo(group4.rotation, { duration: 4, y: -Math.PI * 2, repeat: -1, }, { duration: 20, y: 0, repeat: -1, })
  gsap.fromTo(group4.rotation, { duration: 4, x: -Math.PI * 2, repeat: -1, }, { duration: 20, x: 0, repeat: -1, })
  gsap.fromTo(group5.rotation, { duration: 20, y: -Math.PI * 2, repeat: -1, }, { duration: 20, y: 0, repeat: -1, })
  gsap.fromTo(group6.rotation, { duration: 20, y: -Math.PI * 2, repeat: -1, }, { duration: 20, y: 0, repeat: -1, })
  gsap.fromTo(group7.rotation, { duration: 20, y: -Math.PI * 2, repeat: -1, }, { duration: 20, y: 0, repeat: -1, })
  gsap.fromTo(group8.rotation, { duration: 20, y: -Math.PI * 2, repeat: -1, }, { duration: 20, y: 0, repeat: -1, })
  gsap.fromTo(group9.rotation, { duration: 20, y: -Math.PI * 2, repeat: -1, }, { duration: 20, y: 0, repeat: -1, })
  gsap.fromTo(group2.rotation, { duration: 20, y: -Math.PI * 2, repeat: -1, }, { duration: 20, y: 0, repeat: -1, })
}
/**
 * @description: @zww 监听页面变化
 * @param {*}
 * @return {*}
 */
// window.addEventListener('resize', winResize);
// function winResize(){
//   console.log('画面变化');
//   // 首先更新摄像头
//   camera1.aspect = window.innerWidth / window.innerHeight;
//   // 然后更新摄像机的投影矩阵
//   camera1.updateProjectionMatrix();
//   // 然后更新渲染器
//   renderer1.setSize(window.innerWidth, window.innerHeight);
//   // 屏幕像素比变化设置渲染器的像素比
//   renderer1.setPixelRatio(window.devicePixelRatio);
// }
window.addEventListener('mousemove',(event)=>{
  mouse.x = event.clientX/window.innerWidth-0.5;
  mouse.y - event.clientY/window.innerHeight-0.5
});
let currentPage = 1;
window.addEventListener('scroll',scrollFn);
function scrollFn(event){
  let newPage = Math.round(window.scrollY/window.innerHeight)
 if(newPage!=currentPage){
   console.log("改变了当前页，当前页面是",newPage)
   currentPage = newPage;
   console.log(currentPage)
   console.log()
   gsap.to(arr[currentPage*3].rotation,{
     z:"+="+Math.PI*2,
     duration:1,
   })
   gsap.to(arr[currentPage*3+1].rotation,{
     z:"+="+Math.PI*2,
     duration:1,
   })
   gsap.to(arr[currentPage*3+2].rotation,{
     z:"+="+Math.PI*2,
     duration:1,
   })
   // gsap.to(`.page${currentPage} .pageCan .title h1`,{
   //   rotation:"+=360",
   //   duration:1
   // })
   gsap.fromTo(
       `.page${currentPage} .pageCan .title h1`,
       { x: -300 },
       { x: 0, rotate: "+=360", duration: 1 }
   );
 }

}
